package fm.dongman.modellib.source;

import org.jetbrains.annotations.NotNull;

import fm.dongman.animefm.contractlib.contract.HomeContract;
import fm.dongman.animefm.contractlib.model.HomeDataModel;
import fm.dongman.modellib.local.HomeLocalDataSource;
import fm.dongman.modellib.remote.HomeRemoteDataSource;

/**
 * 获取首页的数据源
 * Created by Admin on 2017/9/27.
 */
public class HomeRepository implements HomeContract.IHomeDataSource {
    private static HomeRepository INSTANCE; // 持有实例

    private HomeRemoteDataSource mRemoteSource; // 网络数据源
    private HomeLocalDataSource mLocalSource; // 本地数据源
    private HomeDataModel mHomeData; // 主页数据模型
    private boolean mCacheIsDirty = true; // 缓存是否是脏数据，是则在网络获取，否则不在网络获取

    private HomeRepository(HomeRemoteDataSource remoteDataSource, HomeLocalDataSource localDataSource) {
        mRemoteSource = remoteDataSource;
        mLocalSource = localDataSource;
    }

    /**
     * @return 获取数据源实例
     */
    public static HomeRepository getInstance(HomeRemoteDataSource remoteDataSource,
                                             HomeLocalDataSource localDataSource) {
        if (INSTANCE == null) {
            INSTANCE = new HomeRepository(remoteDataSource, localDataSource);
        }
        return INSTANCE;
    }

    @Override
    public void getData(@NotNull final LoadSourceCallback<? super HomeDataModel> callback) {
        if (mHomeData != null && !mCacheIsDirty) {
            // 先在内存中获取数据
            callback.onDataLoaded(mHomeData);
            return;
        }
        if (mCacheIsDirty) {
            // 判断这次加载是第一次加载或是刷新操作
            getSourceByRemoteSource(callback);
        } else {
            getSourceByLocalSource(callback);
        }
        // 防止多次向服务器请求
        mCacheIsDirty = false;
    }

    /**
     * 从本地获取数据
     * @param callback 回调
     */
    private void getSourceByLocalSource(@NotNull final LoadSourceCallback<? super HomeDataModel> callback) {
        mLocalSource.getData(new LoadSourceCallback<HomeDataModel>() {
            @Override
            public void onDataLoaded(HomeDataModel dataModel) {
                // 在内存中存储
                mHomeData = dataModel;
                callback.onDataLoaded(mHomeData);
            }

            @Override
            public void onDataLoadFiled() {
                // 在数据库中加载失败后，再向服务器请求数据
                getSourceByRemoteSource(callback);
            }
        });
    }

    /**
     * 在网络上获取数据
     *
     * @param callback 回调
     */
    private void getSourceByRemoteSource(final LoadSourceCallback<? super HomeDataModel> callback) {
        mRemoteSource.getData(new LoadSourceCallback<HomeDataModel>() {
            @Override
            public void onDataLoaded(HomeDataModel dataModel) {
                // 在内存中存储
                mHomeData = dataModel;
                callback.onDataLoaded(mHomeData);
            }

            @Override
            public void onDataLoadFiled() {
                callback.onDataLoadFiled();
            }
        });
    }

    @Override
    public void saveData(HomeDataModel dataModel) {
        // 将数据存入数据库
        mLocalSource.saveData(dataModel);
    }

    @Override
    public void refreshData() {
        // 只有刷新后，第二次加载才会向服务器请求
        mCacheIsDirty = true;
    }

    @Override
    public void offLine() {
        // 直接设置为离线模式加载数据
        mCacheIsDirty = false;
    }
}
